﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

namespace Xww.LCV {
    [Serializable]
    public struct LCSUnit : IEquatable<LCSUnit>, IComparable<LCSUnit>, ISerializable {
        public char AA;
        public int Location;

        public LCSUnit(char aa, int location) {
            AA = aa;
            Location = location;
        }
        public void Offset(int offset) {
            this.Location -= offset;
        }

        public override string ToString() {
            return string.Format("{0}{1}", AA, Location);
        }

        /// <summary>
        /// 重载强制转换操作
        /// </summary>
        /// <param name="str">用于强制转换的字符串</param>
        /// <returns></returns>
        public static explicit operator LCSUnit(string str) {
            int i;
            if (char.IsLetter(str, 0) && int.TryParse(str.Substring(1), out i)) {
                return new LCSUnit(str[0], i);
            }
            else {
                throw new InvalidCastException(string.Format("构建 LCS Unit 的字符串[{0}]不符合规范！\n合法的 LCS Unit 字符串应应包括一个字符和一个数字，如：F8", str));
            }
        }

        #region IEquatable<LCSUnit> members

        public bool Equals(LCSUnit other) {
            return this.AA == other.AA && this.Location == other.Location;
        }

        #endregion

        #region IComparable<LCSUnit> members

        public int CompareTo(LCSUnit other) {
            if (this.Location == other.Location) {
                return this.AA - other.AA;
            }
            else {
                return this.Location - other.Location;
            }
        }

        public int CompareAA(LCSUnit other){
            if (this.AA == other.AA) {
                return this.Location - other.Location;
            }
            else {
                return this.AA - other.AA;
            }
        }

        #endregion

        #region ISerializable 成员

        public void GetObjectData(SerializationInfo info, StreamingContext context) {
            Xww.IO.Serialize.SerializationWriter writer = new Xww.IO.Serialize.SerializationWriter();
            writer.Write(Location);
            writer.Write(AA);
            info.AddValue("data", writer.ToArray());
        }
        private LCSUnit(SerializationInfo info, StreamingContext context) {
            Xww.IO.Serialize.SerializationReader reader = new Xww.IO.Serialize.SerializationReader(
                (byte[])info.GetValue("data", typeof(byte[])));
            Location = reader.ReadInt32();
            AA = reader.ReadChar();
        }

        #endregion
    }
}
